//
//  CModule.m
//  mocha
//
//  Created by Justin Yip on 9/24/13.
//
//

#import "CApplication.h"
#import "CModule.h"
#import "ChamleonJSON.h"


#pragma mark - Application

@interface CApplication ()

@property (nonatomic, strong)NSMutableArray *moduleArray;

@end

@implementation CApplication
@synthesize moduleArray;

#pragma mark Initialize

+(CApplication *)sharedApplication{
    static CApplication *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[CApplication alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}


-(id)init{
    self = [super init];
    if (self){
        self.moduleArray = [[NSMutableArray alloc] init];
    }
    return self;
}

#pragma mark - lifecycle

- (BOOL)application:(id<CApplicationDelegate>)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    uiApplication = application;
    
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(application:didFinishLaunchingWithOptions:)]) {
            [m application:self didFinishLaunchingWithOptions:launchOptions];
        }
    }
    
    return YES;
}

- (void)applicationDidBecomeActive:(UIApplication *)application{
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(applicationDidBecomeActive:)]) {
            [m applicationDidBecomeActive:application];
        }
    }
}

- (void)applicationWillResignActive:(UIApplication *)application{
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(applicationWillResignActive:)]) {
            [m applicationWillResignActive:application];
        }
    }
}

- (void)applicationDidEnterBackground:(UIApplication *)application{
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(applicationDidEnterBackground:)]) {
            [m applicationDidEnterBackground:application];
        }
    }
}

- (void)applicationWillEnterForeground:(UIApplication *)application{
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(applicationWillEnterForeground:)]) {
            [m applicationWillEnterForeground:application];
        }
    }
}


-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken{
    
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(application: didRegisterForRemoteNotificationsWithDeviceToken:)]) {
            [m application:application didRegisterForRemoteNotificationsWithDeviceToken:_deviceToken];
        }
    }
}

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"application token did failed:%@\n",error);
    
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(application:didFailToRegisterForRemoteNotificationsWithError:)]) {
            [m application:application didFailToRegisterForRemoteNotificationsWithError:error];
        }
    }
}

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    
    
    //helper doing
    
    for (CModule *m in self.moduleArray) {
        if ([m respondsToSelector:@selector(application:didReceiveRemoteNotification:)]) {
            [m application:application didReceiveRemoteNotification:userInfo];
        }
    }
}



#pragma mark - Provider methods

-(void)initModulesConfig{
    // Do stuff
    NSURL *configURL = [[NSBundle mainBundle] URLForResource:@"bsl" withExtension:@"json"];
    NSString* configStr=[NSString stringWithContentsOfURL:configURL encoding:NSUTF8StringEncoding error:nil];
    
    id configJSON = [configStr JSONObject];
    
    id notification=[configJSON objectForKey:@"notification"];
    if(notification!=nil && [notification boolValue])
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge];
    
    id showNavigationBar=[configJSON objectForKey:@"showNavigationBar"];
    if(showNavigationBar!=nil){
        //        AppDelegate* appDelegate=(AppDelegate*)[[UIApplication sharedApplication] delegate];
        //        [appDelegate.navController setNavigationBarHidden:[showNavigationBar boolValue]];
        
    }
    
    NSArray *modulesJSON = [configJSON objectForKey:@"modules"];
    for (id moduleJSON in modulesJSON) {
        NSString *moduleName = [moduleJSON objectForKey:@"name"];
        Class moduleClass = NSClassFromString(moduleName);
        CModule *m = [[moduleClass alloc] init];
        if (m != nil) {
            m.name = [moduleJSON objectForKey:@"name"];
            m.identifier = [moduleJSON objectForKey:@"identifier"];
            id splash_start=[moduleJSON objectForKey:@"splash_start"];
            if(splash_start!=nil){
                m.splash_start=[splash_start boolValue];
            }
            
            NSArray* dependOns=[moduleJSON objectForKey:@"dependOn"];
            if([dependOns count]>0){
                m.dependOn=[[NSMutableArray alloc] initWithCapacity:1];
                for(NSDictionary* dict in dependOns){
                    [m.dependOn addObject:[dict objectForKey:@"identifier"]];
                }
            }
            [self.moduleArray addObject:m];
            
            //            [self.moduleDictionary setValue:m forKey:m.identifier];
        } else {
            NSLog(@"%@ not exists.", moduleName);
        }
    }
    
}

-(void)startModule{
    if(uiApplication==nil){
        NSLog(@"CApplication error: please run application:(id<CApplicationDelegate>)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions to set delegate!");
        return;
    }
    for(CModule* module in  self.moduleArray){
        if(module.splash_start){
            
            UIViewController* viewController=[module startMainViewControllerWithParams:nil];
            [uiApplication pushViewController:viewController animated:NO];
            
            
            return;
        }
    }
}

-(UIViewController*)startMainViewControllerWithIdentifier:(NSString*)identifier params:(NSDictionary*)params{

    CModule* module=[self moduleForIdentifier:identifier];
    if(module!=nil){
        UIViewController* viewController=[module startMainViewControllerWithParams:params];
        return viewController;
    }
    return nil;
}

-(void)redirectToModulePage:(NSString*)identifier params:(NSDictionary *)params{
    
    if(uiApplication==nil){
        NSLog(@"CApplication error: please run application:(id<CApplicationDelegate>)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions to set delegate!");
        return;
    }

    
    CModule* module=[self moduleForIdentifier:identifier];
    
    if(module!=nil){
        UIViewController* viewController=[module startMainViewControllerWithParams:params];
        
        [uiApplication pushViewController:viewController animated:YES];
    }
    
    
}

-(void)presentToModulePage:(NSString*)identifier params:(NSDictionary*)params{
    if(uiApplication==nil){
        NSLog(@"CApplication error: please run application:(id<CApplicationDelegate>)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions to set delegate!");
        return;
    }
    
    CModule* module=[self moduleForIdentifier:identifier];
    
    if(module!=nil){
        UIViewController* viewController=[module startMainViewControllerWithParams:params];
        [uiApplication presentViewController:viewController animated:YES];
    }
}

-(void)redirectToPage:(UIViewController*)viewController{
    if(uiApplication==nil){
        NSLog(@"CApplication error: please run application:(id<CApplicationDelegate>)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions to set delegate!");
        return;
    }
    [uiApplication pushViewController:viewController animated:YES];

}

-(void)presentToPage:(UIViewController*)viewController{
    if(uiApplication==nil){
        NSLog(@"CApplication error: please run application:(id<CApplicationDelegate>)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions to set delegate!");
        return;
    }
    [uiApplication presentViewController:viewController animated:YES];
    

}

-(UIViewController*)moduleForViewControllerWithIdentifier:(NSString*)identifier pageIdentifier:(NSString*)pageIdentifier{

    CModule* module=[self moduleForIdentifier:identifier];
    if(module!=nil){
        return [module viewControllerWithPageIdentifier:pageIdentifier];
    }
    return nil;
}

-(CModule*)moduleForIdentifier:(NSString*)identifier{
    for(CModule* module in  self.moduleArray){
        
        if([module.identifier isEqualToString:identifier]){
            for(NSString* dependOn in module.dependOn){
                if(![self moduleForIdentifier:dependOn]){
                    NSLog(@"缺失关联依赖：%@",dependOn);
                    return nil;
                }
                
            }
            return module;
        }
        
    }
    //    return [moduleDictionary objectForKey:identifier];
    return nil;
}

-(NSArray*)modules{
    return self.moduleArray;
}

-(void)dispatchAsyncModules{
    
    dispatch_async(dispatch_get_global_queue(0,0), ^{
        for(CModule* module in  self.moduleArray){
            [module startDispatchAsync];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            for(CModule* module in  self.moduleArray){
                [module finishDispatchAsync];
            }
        });

    });

    
    
}

@end
